﻿using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Threading;
using System.Windows.Input;
using System.Threading;

namespace Com.CodePlex.SPC3.SPbAM {

	/*
	public interface IWorkspaceProvider {
		object Load();
	}

	public class Workspace {

	}

	public class WorkspaceModel : DataModel {

		private string filename;
		private IWorkspaceProvider provider;
		private Workspace workspace;

		public WorkspaceModel(string filename, IWorkspaceProvider provider) {
			this.filename = filename;
			this.provider = provider;
			this.State = ModelState.Fetching;
			if (!ThreadPool.QueueUserWorkItem(new WaitCallback(LoadWorkspace))) {
				this.State = ModelState.Invalid;
			}
		}

		public Workspace Workspace {
			get {
				VerifyCalledOnUIThread();
				return workspace;

			}
			private set {
				VerifyCalledOnUIThread();
				if (workspace != value) {
					workspace = value;
					SendPropertyChanged("Workspace");
				}
			}
		}

		private void LoadWorkspace(object state) {
			double fetchedQuote;
			if (_quoteProvider.TryGetQuote(_symbol, out fetchedQuote)) {
				this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
					new ThreadStart(delegate {
						this.Quote = fetchedQuote;
						this.State = ModelState.Active;
					}));
			} else {
				this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
					new ThreadStart(delegate { this.State = ModelState.Invalid; }));
			}
		}
	}

	public enum ModelState {
		Invalid,
		Fetching,
		Active
	}
	 * */

	public class MainWindowViewModel : WorkspaceViewModel {
		ObservableCollection<WorkspaceViewModel> _workspaces;

		public MainWindowViewModel(string filename) {

		}

		public ObservableCollection<WorkspaceViewModel> Workspaces {
			get {
				if (_workspaces == null) {
					_workspaces = new ObservableCollection<WorkspaceViewModel>();
					_workspaces.CollectionChanged += this.OnWorkspacesChanged;
				}
				return _workspaces;
			}
		}

		private void OnWorkspacesChanged(object sender, NotifyCollectionChangedEventArgs e) {
			if (e.NewItems != null && e.NewItems.Count != 0) {
				foreach (WorkspaceViewModel workspace in e.NewItems) {
					workspace.RequestClose += this.OnWorkspaceRequestClose;
				}
			}

			if (e.OldItems != null && e.OldItems.Count != 0) {
				foreach (WorkspaceViewModel workspace in e.OldItems) {
					workspace.RequestClose -= this.OnWorkspaceRequestClose;
				}
			}
		}

		private void OnWorkspaceRequestClose(object sender, EventArgs e) {
			this.Workspaces.Remove(sender as WorkspaceViewModel);
		}

	}

	//http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
	public class CommandViewModel : ViewModelBase {
		public CommandViewModel(string displayName, ICommand command) {
			if (command == null)
				throw new ArgumentNullException("command");

			base.DisplayName = displayName;
			this.Command = command;
		}

		public ICommand Command { get; private set; }
	}


	public abstract class WorkspaceViewModel : ViewModelBase {
		public string CloseCommand { get; set; }

		public void OnRequestClose() {

		}

		public event PropertyChangedEventHandler RequestClose {
			add {
				//VerifyCalledOnUIThread();
				//propertychanged += value;
			}
			remove {
				//VerifyCalledOnUIThread();
				//propertychanged -= value;
			}
		}
	}

	public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable {

		private PropertyChangedEventHandler propertychanged;

		public string DisplayName { get; set; }
		public bool ThrowOnInvalidPropertyName { get; set; }

		public void Dispose() {

		}

		public void OnDispose() {

		}

		protected virtual void OnPropertyChanged(string propertyName) {
			this.VerifyPropertyName(propertyName);
			if (propertychanged != null) {
				var e = new PropertyChangedEventArgs(propertyName);
				propertychanged(this, e);
			}
		}

		[Conditional("DEBUG")]
		[DebuggerStepThrough]
		public void VerifyPropertyName(string propertyName) {
			if (TypeDescriptor.GetProperties(this)[propertyName] == null) {
				string msg = "Invalid property name: " + propertyName;
				if (this.ThrowOnInvalidPropertyName) {
					throw new Exception(msg);
				} else {
					Debug.Fail(msg);
				}
			}
		}

		public event PropertyChangedEventHandler PropertyChanged {
			add {
				//VerifyCalledOnUIThread();
				propertychanged += value;
			}
			remove {
				//VerifyCalledOnUIThread();
				propertychanged -= value;
			}
		}





		/*
		private ModelState _state;
		private Dispatcher Dispatcher;

		public DataModel() {
			Dispatcher = Dispatcher.CurrentDispatcher;
		}

		[Conditional("Debug")]
		protected void VerifyCalledOnUIThread() {
			Debug.Assert(Dispatcher.CurrentDispatcher == this.Dispatcher, "Call must be made on UI thread.");
		}

		public ModelState State {
			get {
				VerifyCalledOnUIThread();
				return _state;
			}
			set {
				VerifyCalledOnUIThread();
				if (value != _state) {
					_state = value;
					SendPropertyChanged("State");
				}
			}
		}

		protected void SendPropertyChanged(string propertyName) {
			VerifyCalledOnUIThread();
			if (_propertyChangedEvent != null) {
				_propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		 * */
	}
}
